<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf8" />
<title>小Ann</title>
 <script src="jquery.min.js"></script>
 <script src="FileSaver.js"></script>
 <script src="mousetrap.min.js"></script>
 <script src="server.js"></script>

</head>
<style>
body {
	margin: 0.5em;
	padding: 0.5em;
    background: #4a4948;
}
span{
    margin-top: 2em;
    padding-left: 0.1em;
    height: 1em;
    /*float: left;*/
    /*width: 20px;*/
}
a{
    /*float: left;*/
}
.black_overlay{ display: none; position: fixed; top: 0%; left: 0%; width: 100%; height: 100%; background-color: black; z-index:1001; -moz-opacity: 0.6; opacity:.60; filter: alpha(opacity=60); }

.white_content { display: none; position: fixed; top: 25%; left: 25%; width: 50%; height: 50%; padding: 16px; border: 16px solid orange; background-color: white; z-index:1002; overflow: auto; }

.cursor{
    height: 1em;
    width: 2px;
    background-color: #fff;
    float: left;
}
#head{
    padding-bottom: 1em;
    position: fixed;
    top:0em;
    margin: 0em;
    padding: 1em 1em 2px 1em;
    left: 0;
    right: 0;
    background: #DAA520;
    font-size: 1.3em;
}
#import{
    float: left;
    width:50%;
}
#state{
    right: 2em;
    float: right;
}
#main{
    display: inline;
    padding: 1em;
    position: relative;
    width: 100%;
}
#line_number{
    width: 32px;
    margin-top: 4.1em;
    font-size: 1.5em;
    text-align: right;
    padding: 0;
    float: left;
    z-index: -999;
    position: relative;
}
#CurrentContent{
    width: 83%;
	font-size: 1.5em;
    margin-left: 0.2em;
    margin-top: 4.1em;
    margin-bottom: 5em;
    float: left;
    position: relative;
    z-index: -999;

}
#info_list{
    width: 15%;
    float: right;
    position: fixed;
    right: 2em;
    margin-top: 4em;
}
#info_list ul {
    padding: 0em;
    margin-left: 2em;
}
ul li{
        list-style: none;

}
#info_list ul li{

    width: 160px;

}

#info_list ul li p{
    border-style: solid;
    border-color: gray;
    text-align: center;
    width: 100%;
    font-size: 1em;
    position: relative;
    float: left;
    margin: 0.2em;
}
#info_list ul li button{
    border-style: solid;
    border-color: gray;
    width: 40%;
    margin: 0.2em;
    font-size: 1em;

}


#relation_type ul li button{
    border-style: solid;
    border-color: gray;
    width: 25%;
    /*margin: 0.2em;*/
    font-size: 1.2em;

}
#entity_type ul li button{
    border-style: solid;
    border-color: gray;
    width: 25%;
    /*margin: 0.2em;*/
    font-size: 1.2em;

}
#jump{
    margin: 0.5em;
    float: left;
    font-size: 1em;light
}
input,button{
    border-style: solid;
    border-color: gray;
    margin: 0.1em;
    font-size: 1em;
}
#bottom{
    position: fixed;
    bottom: 0;
    margin: 0;
    padding: 2px;
    left: 0;
    right: 0;
    overflow: hidden;
    background: #DAA520;
    font-size: 1.2em;
}
</style>
<script>
</script>
<body>
    <div id="head">
            <h1 style="margin: 1px">小Ann标注工具</h1>
            <div id="import">
            	<a id="filename" style="float: left;margin: 0.2em">先导入文本</a>
            </div>
            <div id="state">
                <a id="progress">当前进度：无</a>
            </div>
    </div>
    <div id="main">
        <ul id="line_number">

        </ul>
        <div id="CurrentContent">

        </div>
        <div id="info_list">
            <ul>
                <li>
                    <input type="file" id="files" style="display: none;" hidefocus="true" onchange="fileImport();">
                    <button style="background:#557766;width: 100%;font-size: 1.3em;" onclick="document.getElementById('files').click()";>导入文本</button>
                    
                </li>
                
                <p style="color:white"><input type="checkbox" id="seqlab_flag" value="序列辅助标注" />序列辅助标注 </p>
                <p style="color:white"><input type="checkbox" id="cursor_auto_run" value="光标自动移动" />光标自动移动 </p>
                <p style="color:white"><input type="checkbox" id="cut_save_flag" value="截断保存" />截断保存 </p>
                <li>
                    <select id="jump">
                    </select>
                    <input type='button' value='跳转' onClick="jump(false)"/>
                </li>
                <li>
                    <p id="annoted_spo" style="background:#A9A9A9">已标注：0 对三元组</p>
                </li>
                <li>
                    <p id="annoted_entity" style="background:#A9A9A9">已标注：0 个新实体</p>
                </li>
                <li>
                    <p id="annoted_relation" style="background:#A9A9A9">已标注：0 个新关系</p>
                </li>
                <li>
                    <p id="cancle_point" style="background:#A9A9A9">已取消：0 个标注点</p>
                </li>
                <li>
                    <button style="background:#4682B4;float: left" onclick="add_entity()">实体</button>
                    <button style="background:#228B22;float: left" onclick="add_relation()">关系</button>
                </li>
                <li>


                <li>
                    <button style="background:#FF00FF;float: left" onclick="cancle()">取消</button>
                </li>
                <li>
                    <button style="background:#008B8B" onclick="save()">保存</button>
                </li>


                <li>
                    <p id="indicator" style="background:gray;width: 40%;right: -40px">已选中</ps>
                </li>
        </div>
    </div>
    <div id="entity_type" class="white_content">
      <p id="given_by_server_e"></p>
      <ul>
        <li><button style="background:#4682B4;float: left;padding: 0.5em" onclick="set_type('实体_实体类型1')">0:实体类型1</button></li>
        <li><button style="background:#4682B4;float: left;padding: 0.5em" onclick="set_type('实体_实体类型2')">1:实体类型2</button></li>
        <li><button style="background:#4682B4;float: left;padding: 0.5em" onclick="set_type('实体_实体类型3')">2:实体类型3</button></li>
        <li><button style="background:#4682B4;float: left;padding: 0.5em" onclick="set_type('实体_实体类型n')">3:实体类型n</button></li>
        <li><button style="background:#4581B3;float: left;padding: 0.5em" onclick="selecte()">空格:默认</button></li>
        <li><button style="background:#FF00FF;float: left;padding: 0.5em" onclick="type_choose_close()">n:取消</button></li>
      </ul>
      <!-- <a href="javascript:void(0)" onclick="type_choose_close()">取消</a> -->
    </div>
    <div id="relation_type" class="white_content">
      <p id="given_by_server_r"></p>
      <ul>
        <li><button style="background:#228B22;float: left;padding: 0.5em" onclick="set_type('关系_关系类型1')">0:关系类型1</button></li>
        <li><button style="background:#228B22;float: left;padding: 0.5em" onclick="set_type('关系_关系类型2')">1:关系类型2</button></li>
        <li><button style="background:#228B22;float: left;padding: 0.5em" onclick="set_type('关系_关系类型3')">2:关系类型3</button></li>
        <li><button style="background:#228B22;float: left;padding: 0.5em" onclick="set_type('关系_关系类型n')">3:关系类型n</button></li>
        <li><button style="background:#218a21;float: left;padding: 0.5em" onclick="selecte()">空格:默认</button></li>
        <li><button style="background:#FF00FF;float: left;padding: 0.5em" onclick="spo_global=[];type_choose_close()">n:取消</button></li>


      </ul>
    </div>
    <div id="fade" class="black_overlay">
    </div>
<div id="bottom">
    <button style="padding: 0.5em" onclick="previous()">上一条</button>
    <a style="margin: 2px">当前选择：</a>

    <a id="selected" style="padding: 0.5em">等你点击或者选择</a>
     <a id="relation" style="padding: 3em;color:#226945;font-size: 1em"></a>
    <a id="number_input" style="padding: 3em;color:#FF0000;font-size: 1.5em "></a>
    <button style="padding: 0.5em;float:right;" onclick="next()">下一条</button>
</div>
<script type="text/javascript">
    var txts;
    var imported_flag=0;

    var current_sample_index=-1;
    var current_char_index=-1;
    var end_char_index=-1;
    var total_char_index=-1;
    var spo_relative_start_index=-1;

    var total=-1;
    var all_samples_loaded=[];
    var all_spos_loaded=[];
    var labels_current=[];
    var spo_global=[];//存储全局spo，采用绝对索引值
    var sp_lock=[];
    var page_predicted=[];
    var start_end;
    var obj_mousedown;
    var obj_mouseup;
    var filename="";
    var contents="";
    var txtselected="";
    var number_input="";
    var type="";
    var type_given_server="";
    var state="";
    var count_new_entity=-1;
    var count_new_relation=-1;
    var count_cancled_point=-1;
    var count_spo_lists=-1;

    var seqlab_flag=false;

    var implicit_relation_flag=false;

    var cursor_timer=-1;
    var cursor_obj=-1;
    var cursor_index=0;

    var lists;

    var selected_flag=false;
    var lock_flag=false;
    keyboard_bind();
    //双击检测用
    var tappedBefore;
    var tappedTimeout;

    var cursor_auto_run;
    var cursor_auto_run_flag=false;

    var cut_save_flag=false;
window.onresize = function(){
    refresh();
}
$("#cut_save_flag").change(function() {
    if(document.getElementById('cut_save_flag').checked) cut_save_flag=true;
    else cut_save_flag=false;
    document.activeElement.blur();
});
$("#seqlab_flag").change(function() {
    if(document.getElementById('seqlab_flag').checked){
      seqlab_flag=true;
      if(seqlab_flag&&page_predicted.indexOf(current_sample_index)==-1){
        page_predicted.push(current_sample_index);
        seq_labing_to_server(seqlab_flag,all_samples_loaded[current_sample_index]);
      }
      refresh();
      indicator('off');
    document.activeElement.blur();
    }
    else seqlab_flag=false;
    document.activeElement.blur();
});
$("#cursor_auto_run").change(function() {
    if(document.getElementById('cursor_auto_run').checked) {
      cursor_auto_run_flag=true;
      new_cursor_auto_run();
    }
    else {
      cursor_auto_run_flag=false;
      clearInterval(cursor_auto_run);//先清除之前的

    }
    document.activeElement.blur();
  });
function new_cursor_auto_run(){
  if(cursor_auto_run_flag){
    clearInterval(cursor_auto_run);//先清除之前的
      cursor_auto_run=setInterval(function(){
        if(state=='modify_able') cursor_right(true);
        }, 600);
    }
    
}
function type_choose(entity_pannel,server_result){
  state="choosing";
  var entity_or_relation= entity_pannel==true? '实体':'关系';
  var result_output=txtselected+'&nbsp&nbsp&nbsp&nbsp';
  for(var key in server_result){
    result_output+=key+" : "+server_result[key]+'&nbsp&nbsp&nbsp&nbsp';
  }
  type_given_server=server_result['预测值'];
  var color=eval(server_result['可信度'])>0.7? 'green':'red';
  if(entity_pannel){
    document.getElementById('given_by_server_e').innerHTML=result_output;//标签和对应概率
    document.getElementById('given_by_server_e').style.color=color;//标签和对应概率
    document.getElementById('entity_type').style.display='block';

  }else{
    document.getElementById('given_by_server_r').innerHTML=result_output;//标签和对应概率
    document.getElementById('given_by_server_r').style.color=color;//标签和对应概率
    document.getElementById('relation_type').style.display='block';
  }
  document.getElementById('fade').style.display='block';
}
function set_type(type_){
  type=type_;
  if(type_=='服务器不可用'){//服务器不可用的情况下按默认选择键，直接关闭选择界面返回
    type_choose_close();
    return;
  }
  if(implicit_relation_flag){//关系不在文本中出现，隐形关系
    // console.log(spo_global.length);//dev
    // console.log(''+spo_global);//dev
    var e1=spo_global[0];
    var e2=spo_global[1];
    spo_global[0]=e1;
    spo_global[1]=type;
    spo_global.push(e2);
    // console.log(''+spo_global);//dev
    save_spo();
    type_choose_close();

    return ;
  }
  if(txtselected!=""){
      // var char=all_samples_loaded[current_sample_index][current_char_index]//old_debug
      var char=all_samples_loaded[current_sample_index][start_end[0]];
      current_char_index=start_end[0];
      if(char!=txtselected[0]){

          current_char_index-=txtselected.indexOf(char);
      }
      var end_char=all_samples_loaded[current_sample_index][end_char_index];
      if(end_char_index!=-1&&end_char!=txtselected[txtselected.length-1]){
          end_char_index+=(txtselected.length-txtselected.indexOf(end_char));
      }
      var start_end_tmp=start_end_index(current_char_index,labels_current[current_sample_index]);//当前选中的文本之前的文本是否有标签？
      if(start_end_tmp[0]!=-1&&start_end_tmp[0]!=start_end[0]) for(var i =start_end_tmp[0];i<start_end[0];i++)labels_current[current_sample_index][i]='O';//清楚选中文本之前的标签
      var sample_x=all_samples_loaded[current_sample_index][current_char_index];//sample_x用于提交服务器
      labels_current[current_sample_index][current_char_index]='B_'+type;

      end_char_index=Math.max(txtselected.length+current_char_index-1,-1);
      if(current_char_index<0||end_char_index<=0)return;
      for (var j = current_char_index+1; j<=end_char_index; j++) {
          sample_x+=all_samples_loaded[current_sample_index][j];//sample_x用于提交服务器
          labels_current[current_sample_index][j]='I_'+type;
      }
      cursor_index=end_char_index;
      if(type.indexOf('实体')!=-1) count_new_entity+=1;
      else if(type.indexOf('关系')!=-1) count_new_relation+=1;

      for(var j = end_char_index+1;j<labels_current[current_sample_index].length;j++){//选中修改后，处理之前标记的结果
          if(labels_current[current_sample_index][j][0]!="I")break
              labels_current[current_sample_index][j]="O";
      }
      for(var j = end_char_index+1;j<labels_current[current_sample_index].length;j++){//选中修改后，处理之前标记的结果
          if(labels_current[current_sample_index][j][0]!="I")break
              labels_current[current_sample_index][j]="O";
      }
      // spo_global=[];
      // refresh();
  }else if(start_end[0]!=-1){//直接按下s或f，修改两个字符的标签
          if(start_end[1]==-1){
              var sample_x=all_samples_loaded[current_sample_index][start_end[0]];//sample_x用于提交服务器
              sample_x+=all_samples_loaded[current_sample_index][start_end[0]+1];//sample_x用于提交服务器

              labels_current[current_sample_index][start_end[0]]='B_'+type;
              labels_current[current_sample_index][start_end[0]+1]='I_'+type;
              cursor_index=start_end[0]+1;
              if(type.indexOf('实体')!=-1) count_new_entity+=1;
              else if(type.indexOf('关系')!=-1) count_new_relation+=1;
          }else{
              var sample_x=all_samples_loaded[current_sample_index][start_end[0]];//sample_x用于提交服务器
              labels_current[current_sample_index][start_end[0]]='B_'+type;
              for (var j = start_end[0]+1; j<=start_end[1]; j++) {
                  labels_current[current_sample_index][j]='I_'+type;
                  sample_x+=all_samples_loaded[current_sample_index][j];//sample_x用于提交服务器

              }
              cursor_index=start_end[1];
              if(type.indexOf('实体')!=-1) count_new_entity+=1;
              else if(type.indexOf('关系')!=-1) count_new_relation+=1;
      }
    }
  type_choose_close();
  if(type!=""&type_given_server!='服务器不可用'&type!=type_given_server) to_server(true,true,sample_x,type);
  txtselected="";
  spo_global=[];
  refresh();
}
function save_spo(){
            // console.log(spo_global);//dev
  //得出实际存储位置的索引值 

            var sample_index2store=total_char_index_2_relative_index(spo_global[0])[0];
           
            var exist_index=queery_2dlist(all_spos_loaded[sample_index2store],spo_global);
            if(exist_index==-1){//是否已经存在
                  all_spos_loaded[sample_index2store].push(spo_global);
                  // console.log(''+all_spos_loaded[sample_index2store]);
                  // console.log(sample_index2store);
                  count_spo_lists+=1;
            }else{
                  all_spos_loaded[sample_index2store].splice(exist_index,1);
           }


            //处理跨页面三元组  start
            for(var i=1;i<spo_global.length;i++){//从1开始
                if(spo_global[i][0]=='关')continue;//隐性关系
                var sample_overlap_index=total_char_index_2_relative_index(spo_global[i])[0];
                var exist_index_other_page=queery_2dlist(all_spos_loaded[sample_overlap_index],spo_global);
                // console.log(exist_index_other_page);//dev
                if(exist_index==-1&&exist_index_other_page==-1){//没有存储过的三元组
                  all_spos_loaded[sample_overlap_index].push(spo_global);
                  // console.log('添加跨页面三元组！');//dev
                  // console.log(sample_overlap_index,spo_global);//dev
                }else if(exist_index!=-1&&exist_index_other_page!=-1){//储存过的三元组，进行删除
                  all_spos_loaded[sample_overlap_index].splice(exist_index_other_page,1);
                }
            }
          //处理跨页面三元组  end

          spo_global=[];
          indicator('off');
          clean_rectangle();
          refresh();
           //恢复之前锁定元素  start
            if(sp_lock.length!=0){
                  spo_global=[];
                for(var i in sp_lock){
                  var se_tmp=start_end_index(total_char_index_2_relative_index(parseInt(sp_lock[i]))[1],labels_current[current_sample_index]);
                  if(i==1&&labels_current[current_sample_index][se_tmp[0]][2]=='实')break;//两个实体被锁定，只取第一个锁定的实体
                  render_rectangle(se_tmp);
                  spo_global.push(sp_lock[i]);
                }
                // indicator('on');
            }else{
              spo_global=[];
              indicator('off');
            }//恢复之前锁定元素 end
}
function set_labels(labels_result){
  var labels_tmp=labels_result['预测值'];
  var probability_tmp=labels_result['可信度'];
  if(labels_tmp.length!=(labels_current[current_sample_index].length)){
    console.log('服务器的标签结果长度存在问题！');
    return;
  }else
  {
  for(var i=0;i<labels_tmp.length;i++){
    if(eval(probability_tmp[i])>0.4) {//根据置信度调整标签
      labels_current[current_sample_index][i]=labels_tmp[i];
    }
    else continue;
  }

  }
  for(var i=0;i<labels_tmp.length-1;i++){//再次检查根据置信度调整后的标签连续性
    var labels_to_check=labels_current[current_sample_index];
    //单独出现I标签
    if(i==0&&labels_to_check[i][0]=="I")labels_current[current_sample_index][i]='O';
    if(labels_to_check[i][0]=="O"&&labels_to_check[i+1][0]=="I")labels_current[current_sample_index][i+1]='O';
  }
  refresh()//等待服务器结果后进行刷新，不可删除
}
function type_choose_close(){
   implicit_relation_flag=false;
   document.getElementById('entity_type').style.display='none';
   document.getElementById('relation_type').style.display='none';
   document.getElementById('fade').style.display='none';
   state="modify_able";
   txtselected="";
   if(!lock_flag){
    spo_global=[];
    }
   clean_rectangle();
   indicator('off');
}
function jump(vim){
    if(state!="modify_able")return;
    if(vim==false){
        obj = document.getElementById("jump");
        current_sample_index=parseInt(obj.value);
    }else{
        if(number_input.length==0)return;
        var tmp=eval(number_input);

      current_sample_index=tmp<0?0:tmp;
      current_sample_index=current_sample_index>=all_samples_loaded.length?all_samples_loaded.length-1:current_sample_index;
    }

    spo_global=[];
    sp_lock=[];
    change_cursor_index(0);
    number_record('clean');
    if(seqlab_flag&&page_predicted.indexOf(current_sample_index)==-1){
      page_predicted.push(current_sample_index);
      seq_labing_to_server(seqlab_flag,all_samples_loaded[current_sample_index]);
    }

    refresh();
    indicator('off');
    document.activeElement.blur();
    //初始化视野
    var position=cursor_obj.getBoundingClientRect();
    view_adjust(position);
}

function selecte(){
    if(state=='choosing'){
      set_type(type_given_server);
      type_given_server="";
      spo_global=[];
      return;
    }
    if(selected_flag||sp_lock.length!=0||spo_global.length!=0){//取消已选中，锁定的元素，清楚选中的三元组
        indicator('off');
        selected_flag=false;
        lock_flag=false;
        txtselected="";
        sp_lock=[];
        spo_global=[];
        clean_rectangle();
    }else{
        selected_flag=true;
        indicator('on');
        obj_mousedown=lists[cursor_index];
        render_rectangle([cursor_index,cursor_index]);
    }
}
function next(key_triger){
    if(state=="choosing"){
      spo_global=[];
      type_choose_close();
      return;
    }
    if(state!="modify_able")return;
    if(number_input!="") var page_change=eval(number_input);
    else var page_change=1;
    if((current_sample_index+page_change)>total){//超出范围
        current_sample_index=total;
        cursor_index=all_samples_loaded[current_sample_index].length-1;
    }else{
      cursor_index=0;
      current_sample_index+=page_change;
    }
    number_record('clean');
    if(seqlab_flag&&page_predicted.indexOf(current_sample_index)==-1){
      page_predicted.push(current_sample_index);//记录当前被服务器预测过的页码
      seq_labing_to_server(seqlab_flag,all_samples_loaded[current_sample_index]);
    }
    refresh();
    document.activeElement.blur();
}
// function change_page()
function previous(key_triger){
    if(state=='choosing'){
      number_record('11');
      return;
    }
    if(state!="modify_able")return;
    if(number_input!="") var page_change=eval(number_input);
    else var page_change=1;
    if((current_sample_index-page_change)<0){//超出范围
        current_sample_index=0;
        cursor_index=0;
    }else{
    current_sample_index-=page_change;
    cursor_index=all_samples_loaded[current_sample_index].length-1;

    }
    number_record('clean');
    if(seqlab_flag&&page_predicted.indexOf(current_sample_index)==-1){
      page_predicted.push(current_sample_index);
      seq_labing_to_server(seqlab_flag,all_samples_loaded[current_sample_index]);
    }
    refresh();
    document.activeElement.blur();
    
}
    //屏蔽空格页面下滑
    document.onkeydown = function(ev){
      var e = ev || event;
      if(e.keyCode == 32){
            return false;
      }
    }
  //屏蔽ctl+g
  document.onkeydown = function(ev){
    var e = ev || event;
    if (e.ctrlKey && e.keyCode==71){
      return false;
    }
  }
function keyboard_bind(){
     Mousetrap.bind('s', function() { add_entity(); });
     Mousetrap.bind('f', function() { add_relation(); });
     Mousetrap.bind('a', function() { cancle(); });
     Mousetrap.bind('h', function() { cursor_left(); });
     Mousetrap.bind('g', function() { cursor_left_twice(); });
     Mousetrap.bind('l', function() { cursor_right(); });
     Mousetrap.bind(';', function() { cursor_right_twice(); });
     Mousetrap.bind('j', function() { cursor_down(); });
     Mousetrap.bind('k', function() { cursor_up(); });
     Mousetrap.bind('n', function() { next(true); });
     Mousetrap.bind('b', function() { previous(true); });
     Mousetrap.bind('c', function() { number_record('12'); });
     Mousetrap.bind('d', function() { number_record('13'); });
     Mousetrap.bind('e', function() { forward(); });
     Mousetrap.bind('r', function() { forward_end(); });
     Mousetrap.bind('w', function() { back(); });
     Mousetrap.bind('0', function() { number_record('0'); });
     Mousetrap.bind('1', function() { number_record('1'); });
     Mousetrap.bind('2', function() { number_record('2'); });
     Mousetrap.bind('3', function() { number_record('3'); });
     Mousetrap.bind('4', function() { number_record('4'); });
     Mousetrap.bind('5', function() { number_record('5'); });
     Mousetrap.bind('6', function() { number_record('6'); });
     Mousetrap.bind('7', function() { number_record('7'); });
     Mousetrap.bind('8', function() { number_record('8'); });
     Mousetrap.bind('9', function() { number_record('9'); });
     Mousetrap.bind('p', function() { keyboard_spo(); });
     Mousetrap.bind('enter', function() { jump(true); });
     Mousetrap.bind('esc', function() { number_record('clean'); });
     Mousetrap.bind('ctrl+g', function(){ jump_2_char_total_index();});
     Mousetrap.bind('space', function() { selecte(); });
     
}
function jump_2_char_total_index(){
  if(state!="modify_able"||number_input.length==0)return;
  var total_char_index_tmp=eval(number_input);
  var result_tmp=total_char_index_2_relative_index(total_char_index_tmp);
  if(result_tmp[0]==-1)return;
  current_sample_index=result_tmp[0];
  cursor_index=result_tmp[1];
  refresh();
  number_record('clean');
}
function number_record(number_char){//记录输入的数字，并判断是否在选择页面
    if(isNaN(number_char))number_input="";
    else number_input+=number_char;
    document.getElementById('number_input').innerHTML=number_input;
    if(state=="choosing"){
      option_choosed=eval(number_input);
      var testobj=document.getElementById('entity_type');
      if(testobj.style.display=='none') testobj=document.getElementById('relation_type');
      var options = Array.from(testobj.querySelectorAll('button'));
      if(option_choosed>=0& option_choosed<options.length){
        options[option_choosed].click();
      }
      number_input="";
      return;
    }
}
function keyboard_spo(){
  if(state!="modify_able")return;
  var tappedNow = cursor_index;
      if (tappedTimeout && tappedBefore) {
        clearTimeout(tappedTimeout);
      }
      if(tappedBefore === tappedNow) {
        tappedBefore = null;
        click_handle(cursor_index,true);
      } else {
        tappedTimeout = setTimeout(function(){
            tappedBefore = null;
            click_handle(cursor_index,false);
        }, 195);
        tappedBefore = tappedNow;

      }
    // var start_end=start_end_index(current_char_index,labels_current[current_sample_index]);
    //     total_char_index=total_char_index_cal(start_end[0]);
    //     var cursor_next=cursor_index;
    //     cursor_index=start_end[0];
    //     cursor_obj=lists[cursor_index];
    //     cursor_obj.style.color='#4a4948';
    //     render_rectangle(start_end);
    //     spo_record(start_end);
}
function forward_end(){
    if(state!="modify_able")return;
    var cursor_next=cursor_index;
    //当前位置的标签是’O‘
    var condition1=labels_current[current_sample_index][cursor_next][0]=='O';
    //存在下一个位置且当前位置下一个标签是’O‘或者’B'
    var condition2=(cursor_next+1)<lists.length&&['O','B'].indexOf(labels_current[current_sample_index][cursor_next+1][0])!=-1;
    if((cursor_next+1<lists.length)){
        if(condition1||condition2){
            for(var i=cursor_next+1;i<lists.length;i++)if(labels_current[current_sample_index][i][0]=='B') break
            var begin_tmp=i==lists.length? i-1:i;
        }else var begin_tmp=cursor_next;
    }
    else var begin_tmp=lists.length-1;
    var location_tmp=start_end_index(begin_tmp,labels_current[current_sample_index])[1];
    cursor_next= location_tmp>=0? location_tmp:cursor_next;
    change_cursor_index(cursor_next);
    cursor();
}

function forward(){
    if(state=='choosing'){
      number_record('14');
      return;
    }
    if(state!="modify_able")return;
    if(cursor_index+1>=lists.length )next(true);
    var cursor_next=cursor_index;
    for(var i=cursor_next+1;i<lists.length;i++)if(labels_current[current_sample_index][i][0]=='B') break
    cursor_next=i==lists.length? i-1:i;
    change_cursor_index(cursor_next);
    cursor();
}
function back(){
    if(state!="modify_able")return;
    if(cursor_index-1<0)previous(true);
    var cursor_next=cursor_index;
    for(var i=cursor_next-1;i>0;i--)if(labels_current[current_sample_index][i][0]=='B') break
    cursor_next=i<0? 0:i;
    change_cursor_index(cursor_next);
    cursor();
}
function cursor_down(){
    if(state!="modify_able")return;
    var cursor_next=cursor_index;
    if(number_input!="") var line_change=eval(number_input);
    else var line_change=1;
    number_input="";
    document.getElementById('number_input').innerHTML="";
    for(var j=0;j<line_change;j++){
        var position=lists[cursor_next].getBoundingClientRect();

        var distance=[];
        for(var i=cursor_next;i<lists.length;i++){
            var position_tmp=lists[i].getBoundingClientRect();
            if(Math.abs(position.y-position_tmp.y)<10){
                distance.push(9999);
                continue;
            }
            distance.push(Math.abs(position_tmp.y-position.y)+Math.abs(position_tmp.x-position.x));
        }
        if(distance[distance.length-1]==9999){
            cursor_index=cursor_index;
            next(true);
            return;
        }else   cursor_next+=distance.indexOf(Math.min.apply(null,distance));
    }
    change_cursor_index(cursor_next);
    cursor();
}
function cursor_up(){
    if(state!="modify_able")return;
     var cursor_next=cursor_index;
    if(number_input!="") var line_change=eval(number_input);
    else var line_change=1;
    number_input="";
    document.getElementById('number_input').innerHTML="";
    for(var j=0;j<line_change;j++){
        var position=lists[cursor_next].getBoundingClientRect();

        var distance=[];
        for(var i=cursor_next;i>0;i--){
            var position_tmp=lists[i].getBoundingClientRect();
            if(Math.abs(position.y-position_tmp.y)<10){
                distance.push(9999);
                continue;
            }
            distance.push(Math.abs(position_tmp.y-position.y)+Math.abs(position_tmp.x-position.x));

        }
        if(cursor_next==0||distance[distance.length-1]==9999){
            cursor_index=cursor_index;

            previous(true);
            return;
        }
        cursor_next-=distance.indexOf(Math.min.apply(null,distance));
    }
    change_cursor_index(cursor_next);
    cursor();
}
function cursor_left_twice(){
  cursor_left();
  cursor_left();
}
function cursor_left(){
    if(state!="modify_able")return;
    var cursor_next=cursor_index;
    if(number_input!="") cursor_next-=eval(number_input);
    else cursor_next-=1;
    number_input="";
    document.getElementById('number_input').innerHTML="";
    if(cursor_next<0){
        previous(true);
        return;
    }
    change_cursor_index(cursor_next);
    cursor();
}
function cursor_right_twice(){
  cursor_right();
  cursor_right();
}
function cursor_right(auto_flag=false){
    if(state!="modify_able")return;
    var cursor_next=cursor_index;
    if(number_input!="") cursor_next+=eval(number_input);
    else cursor_next+=1;
    number_input="";
    document.getElementById('number_input').innerHTML="";
    if(cursor_next>=lists.length){
        next(true);
        return;
    }
    change_cursor_index(cursor_next);
    cursor();
}

function start_end_index(index,label){
    // console.log(index,label);//debugs
    var start_index=-1;
    var end_index=-1;
    if(index<0||index>label.length)return[-1,-1];
    if(label[index][0]=="O"){
        if(selected_flag) return [index,index];
        else return [index,-1];
    }
    if(label[index][0]=="B"){//刚好index是实体（关系）的起点索引，只需寻找结尾索引
        var start_index=index;
        for(var i=index+1;i<label.length;i++)if(label[i][0]!="I")break;
        var end_index=i-1;
        return [start_index,end_index];
    }else{//index位于中间，先寻左边的起点索引，再寻找右边的结尾索引
            for(var i=index-1;i>0;i--)if(label[i][0]!="I")break;
            if(i==0&&label[i][0]!="B"){
                alert(total_char_index+"处数据存在问题，找不到标记起始");
                return [-1,-1];
            }
            start_index=i;
            for(var i=index+1;i<label.length;i++){
                if(label[i][0]!="I")break;
            }
            end_index=i-1;
            return [start_index,end_index];
        }
}
function view_adjust(position){
    var testobj=document.getElementById('CurrentContent');

    if(position.y>550){
        document.documentElement.scrollTop+=(position.y-550);
    }
    if(position.y<152){
        document.documentElement.scrollTop-=(152-position.y);
    }
}
function cursor(){
    new_cursor_auto_run();
    cursor_obj=lists[cursor_index];
    // window.location.hash="#span"+cursor_index;
    try{
      var position=cursor_obj.getBoundingClientRect();
    }
    catch(err){
      console.log('异常!');
      // console.log()
      console.log(cursor_index);
      console.log('置为0');
      cursor_index=0;
      return;
    }
    //跟随光标调整视野
    view_adjust(position);

    //闪烁光标
    if(cursor_timer!=-1)clearInterval(cursor_timer);
    cursor_timer=setInterval("flash(cursor_obj)",400);

    //空格选中文本
    if(selected_flag){
        obj_mouseup=lists[cursor_index];
        // var start_end_tmp=[lists.indexOf(obj_mousedown),lists.indexOf(obj_mouseup)];
        txtselected="";
        for(var i=lists.indexOf(obj_mousedown);i<=cursor_index;i++)txtselected+=lists[i].innerHTML;
        if(lists.indexOf(obj_mouseup)<lists.indexOf(obj_mousedown)){
            selected_flag=false;
            indicator('off');
            clean_rectangle();
            return;
        }
        start_end=[lists.indexOf(obj_mousedown),lists.indexOf(obj_mouseup)];
        current_char_index=start_end[0];
        end_char_index=start_end[1];
        clean_rectangle();
        render_rectangle(start_end);
        return;
    }

    //按照光标位置改变current_char_index
    current_char_index=cursor_index;
    bottom_display(current_char_index);

}
function change_cursor_index(next_cursor_index){
    // console.log(cursor_obj.innerHTML);//tmp
    if(next_cursor_index==-1)return;
    try{
        cursor_obj.style.color='#DAA520';//恢复正常颜色
    }
    catch(err){

    }
    cursor_index=next_cursor_index;
    cursor_obj=lists[cursor_index];
    cursor_obj.style.color='#4a4948';//快速变黑，实时反馈

}
function bottom_display(current_char_index){
  var selected_obj=document.getElementById("selected");
    var start_end_tmp=start_end_index(current_char_index,labels_current[current_sample_index]);
    var total_char_index_tmp=total_char_index_cal(start_end_tmp[0]);
    selected_obj.innerHTML=lists[cursor_index].innerHTML+" : "+current_char_index+" : "+total_char_index_tmp+" : "+labels_current[current_sample_index][current_char_index];
    var relation_obj=document.getElementById("relation");
    relation_obj.innerHTML="";
    if(lists[start_end_tmp[0]].Id!=undefined){
        var relations_tmp=lists[start_end_tmp[0]].Id.split(';');
        for(var re in relations_tmp)   relation_obj.innerHTML+=re+':'+relations_tmp[re].slice(3)+'&nbsp';
    }
}
function flash(obj){//光标闪烁
    if(obj.style.color=='rgb(218, 165, 32)')obj.style.color='#4a4948';
    else{obj.style.color='#DAA520'}
}

function little_correction(relative_index,label){
    var correction=0;
    // try{
      label[relative_index][0]!='B'
    // }
    // catch(err){
      // console.log('异常');
      // console.log(relative_index,label.length);
      // return correction;
    // }
    if(label[relative_index][0]!='B'){
        console.log('发现错位！');
        if(label[relative_index-1][0]=='B')correction=-1;
        else if(label[relative_index+1][0]=='B')correction=1;
        else{
            console.log('该错误无法修正:');
            console.log(relative_index,label[relative_index]);
        }
    }
    return correction;
}
// function text2obj_color(text,label,spos){
function text2obj_color(text,label,spos){
    var display_start_y=-1;
    var line_number=0;
    var text=all_samples_loaded[current_sample_index];
    var label=labels_current[current_sample_index];
    var testobj=document.getElementById("CurrentContent");
    var line_number_display_obj=document.getElementById("line_number");
    testobj.innerHTML="";
    line_number_display_obj.innerHTML="";
    for(var c in text){
        var char = document.createElement('span');
        char.id='span'+c;
        char.style.color='#DAA520';
        // if(label[c][0]=="B" || label[c][0]=="O"){
        //     var cursor_obj = document.createElement('div');
        //     cursor_obj.className="cursor";
        //     testobj.appendChild(cursor_obj);
        // }

        char.innerHTML = text[c]==" "?"&nbsp;":text[c];

        //实体关系可视化
        if(label[c].length>2){
            if(label[c][2]=="实") char.style.backgroundColor="#4682B4";
            else if(label[c][2]=="关") char.style.backgroundColor="#228B22";
            if(label[c][0]=="B") char.style.marginLeft="0.2em";
        }
        if(text[c]=="\n"){
            char.style.backgroundColor="#00FF7F";//突出换行符
            char.style.paddingLeft='0em';
            // char.style.width="2px";
            char.innerHTML='|';
            testobj.appendChild(char);
            var br = document.createElement('br');//显示换行

            if(c!=0) testobj.appendChild(br);//首字符为换行的不显示
        }else  testobj.appendChild(char);//这一批样本首字符为换行符，统计但不显示
        // var length_tmp=Array.from(testobj.querySelectorAll('span')).length;
    // if(length_tmp%25==0){//限定每行字符数
    //     var br = document.createElement('br');//显示换行
    //     testobj.appendChild(br);
    // }
    }

    // var testobj=document.getElementById("CurrentContent");
    lists = Array.from(testobj.querySelectorAll('span'));
    //三元组可视化
    for(var i1=-1;i1<2;i1++){//左右检查跨页面三元组end
      if((current_sample_index+i1)<0||(current_sample_index+i1>=all_spos_loaded.length))continue;//跳过超出范围的i1
      var spos_tmp=all_spos_loaded[current_sample_index+i1];//取出该页面的三元组
      if(spos_tmp.length>1){//如果该页面三元组存在标注结果
            for(var i=1;i<spos_tmp.length;i++){//遍历三元组标注结果
                var spo=spos_tmp[i];
                var page_2_add=[];
                // console.log(''+spo);
                for(var j in spo){//s,p,o，先对各个元素进行修正，并判断需要在哪些页面添加三元组
                    if(spo[j][0]=='关') continue;//跳过隐式关系
                    var page_relative_index=total_char_index_2_relative_index(parseInt(spo[j]));
                    if(j==0) var page=page_relative_index[0];//在三元组存储的页面进行索引值修正
                    var relative_index=page_relative_index[1];
                    if(page_2_add.indexOf(page_relative_index[0])==-1){
                        page_2_add.push(page_relative_index[0]);
                    }
                    label=labels_current[page_relative_index[0]];//取出该页面的标签
                    var correction=little_correction(relative_index,label);
                    if(correction!=0){
                    }
                    // console.log(spo);//dev
                    // console.log(page,i,j);//dev
                    // console.log(''+all_spos_loaded[page]);//dev
                    // console.log(''+all_spos_loaded[current_sample_index+i1]);//dev
                    //i不一样
                    var index_tmp=queery_2dlist(all_spos_loaded[page],spo);
                    // console.log(index_tmp);//dev
                    all_spos_loaded[page][index_tmp][j]=(parseInt(all_spos_loaded[page][index_tmp][j])+correction)+'';//修正指标
                    spo[j]=(parseInt(spo[j])+correction)+'';

                }
            for(var page in page_2_add){//对需要添加三元组的页面添加三元组
                var condition3=queery_2dlist(all_spos_loaded[page_2_add[page]],spo)==-1;//是否已经添加跨界三元组？
                    if(condition3){
                        all_spos_loaded[page_2_add[page]].push(spo);
                    }                 
            }
            }//s,p,o end        
        }
    }//左右检查跨页面三元组end
    var spos=all_spos_loaded[current_sample_index];
    var label=labels_current[current_sample_index];
    // var tag=["S","P","O"];
    var colors=["#FF0000","#32CD32","#1E90FF"];
    if(spos.length>1){
        var this_page_index=parseInt(spos[0][0]);
        for(var i=1;i<spos.length;i++){
            var spo=spos[i];
            for(var j in spo){//s,p,o
                if(spo[j][0]=='关')continue;
                var relative_index=parseInt(spo[j])-this_page_index;
                if(relative_index<0||relative_index>=label.length)continue;//跳过不是本页的元素
                var correction=little_correction(relative_index,label);
                  if(correction!=0){
                  }
                  all_spos_loaded[current_sample_index][i][j]=(relative_index+this_page_index+correction)+'';
                  relative_index+=correction;
                var a_object=document.createElement("a");
                a_object.style.marginLeft="0.2em";
                a_object.innerHTML=i;
                a_object.style.fontSize="0.8em";
                a_object.style.backgroundColor=colors[j];
                if(lists[relative_index].Id!=undefined){
                      lists[relative_index].Id+=';'+spo[1];
                }else lists[relative_index].Id=spo[1];
                testobj.insertBefore(a_object,lists[relative_index]);
              }
      }
    }


//所有标记显示完毕，最后添加行号
    var distance_y=[];
    for(var i in lists){
        var current_y=lists[i].getBoundingClientRect().y;
        if(distance_y.indexOf(current_y)==-1){
            distance_y.push(current_y)
            var line_number_obj=document.createElement('li');
            line_number_obj.style.margin="0 auto";
            line_number_obj.style.width="32px";
            line_number_obj.innerHTML=line_number;
            line_number_obj.style.backgroundColor="#66CDAA";
            $("#line_number").append(line_number_obj);
            line_number++;
        }

    }

    //显示锁定的三元组


    if(sp_lock.length!=0){
      spo_global=[];
      for(var i in sp_lock){
          var location_tmp=total_char_index_2_relative_index(sp_lock[i]);
          if(location_tmp[0]==current_sample_index) {
            var se_tmp=start_end_index(location_tmp[1],labels_current[current_sample_index]);
            if(i==1&&labels_current[current_sample_index][se_tmp[0]][2]=='实')break;//两个实体被锁定，只取第一个锁定的实体
            render_rectangle(se_tmp);
            spo_global.push(sp_lock[i]);
          }
    }
    indicator('on');
    }

    //显示锁定的三元组 end
    


}
function text2obj(text){
  var testobj=document.getElementById("CurrentContent");
  testobj.innerHTML="";
  for(var c in text){
        if(c==0&&text[c]=='\n')continue;
    var char = document.createElement('span');
    var a = document.createElement('a');
    char.innerHTML = text[c];
    testobj.appendChild(char);
  }
}
function render_rectangle(start_end_tmp,number=-1){//将本页面的start_end画矩形
    if(start_end_tmp[0]==-1||start_end_tmp[1]==-1)return;

    var colors=["#FF0000","#32CD32","#1E90FF"];
    var borderw='1px';
    var start_obj=lists[start_end_tmp[0]];
    var end_obj=lists[start_end_tmp[1]];
    var color_n=number==-1?spo_global.length:number;
    start_obj.style.borderLeft="solid";
    start_obj.style.borderTop="solid";
    start_obj.style.borderBottom="solid";
    start_obj.style.borderWidth=borderw;
    // start_obj.style.fontSize="1.1em";
    start_obj.style.borderColor=colors[color_n];
    end_obj.style.borderRight="solid";
    end_obj.style.borderTop="solid";
    end_obj.style.borderBottom="solid";
    end_obj.style.borderWidth=borderw;
    // end_obj.style.fontSize="1.1em";
    end_obj.style.borderColor=colors[color_n];
    for(var i=start_end_tmp[0]+1;i<start_end_tmp[1];i++){
        var span_obj=lists[i];
        span_obj.style.borderTop="solid";
        span_obj.style.borderBottom="solid";
        span_obj.style.borderLeft="none";
        span_obj.style.borderRight="none";
        span_obj.style.borderColor=colors[color_n];
        span_obj.style.borderWidth=borderw;
        // span_obj.style.fontSize="1.1em";

    }
}
function save(){
    spo_global=[];
    if(imported_flag==0)return;
    var results=""
    var labels_result=[];
    var tokens_result=[];
    var spo_result=[];

    //实体和关系
    for (var i = 0; i <labels_current.length; i++) {
        for (var j = 0; j<labels_current[i].length; j++) {
            var l=labels_current[i][j];
            var t=all_samples_loaded[i][j]=="\n"? "_换行符_":all_samples_loaded[i][j];
            if(l==undefined){
                alert('l发现问题'+l);
                return;
            }
            if(t==undefined){
                alert('t发现问题'+t);
                return;
            }
            labels_result.push(l);
            tokens_result.push(t);

            spo_result.push("X");//初始化三元组域
        }

    }
    //三元组
    for(var i in all_spos_loaded){//遍历每个页面的三元组列表
        if(all_spos_loaded[i].length==1)continue;//每个all_spos_loaded[i]第一个元素为分割索引值

        for(var j=1;j<all_spos_loaded[i].length;j++){//遍历当前页面下所有的三元组列表
            if(all_spos_loaded[i][j][0]=='X'||all_spos_loaded[i][j][1]=='X'||all_spos_loaded[i][j][2]=='X') continue;
            var spo_tmp=all_spos_loaded[i][j];
            var page_2_store=total_char_index_2_relative_index(parseInt(spo_tmp[0]))[0];
            if(page_2_store==i)  spo_result[parseInt(spo_tmp[0])]+=";"+spo_tmp.join(">");//只储存应该存在当页的三元组，排除补充的跨界三元组，避免重复存储
        }

    }
    //字符 标签 三元组汇总
    for(var i in spo_result){
        if(spo_result[i][1]==";"){
            spo_result[i]=spo_result[i].replace("X;","");
        }
        var t=tokens_result[i];
        var l=labels_result[i];
        if(l==undefined){
            console.log(i);
            console.log(labels_result.length);
            alert('汇总时，l发现问题'+l);
            return;
        }
        if(t==undefined){
            console.log(i);
            console.log(tokens_result.length);
            alert('汇总时，t发现问题'+t);
            return;
            }
        results+=t+"\t"+l+"\t"+spo_result[i]+"\n";
        if(cut_save_flag)if(i==total_char_index_cal(cursor_index)){
          break;
        }

    }
    var filename_tmp=filename;
    var blob = new Blob([results], {type: "text/plain;charset=utf-8"});
    if(current_sample_index==all_samples_loaded.length-1)filename_tmp='x '+filename_tmp;
    if(cut_save_flag)filename_tmp+='cutted';
    saveAs(blob,  filename_tmp+"#"+current_sample_index+"#"+".lann");
}
function indicator(on_off){
    var indicator_obj=document.getElementById("indicator");
    if(on_off=='on'){
         indicator_obj.style.backgroundColor="pink";
         // this.cursor='url(cur.ico),auto';
        // for(var i in lists) lists[i].style.cursor='pointer';
        for(var i in lists) lists[i].style.cursor='url('+spo_global.length+'.png),auto';
         // document.getElementById("span").style.cursor='pointer';
         // this.css({cursor:"pointer"});
    }
    else{
         indicator_obj.style.backgroundColor="gray";
        for(var i in lists) {
            if(labels_current[current_sample_index][i][2]=='实') var cursor_style='url(0.png),auto';
            else var cursor_style='default';
            lists[i].style.cursor=cursor_style;
        }

    }
}
function refresh(){
    var progress_obj=document.getElementById("progress");
    progress_obj.innerHTML="当前进度："+current_sample_index+"/"+total;
    // text2obj_color(all_samples_loaded[current_sample_index],labels_current[current_sample_index],all_spos_loaded[current_sample_index]);
    clean_rectangle();
    text2obj_color();
    var annoted_spo_obj=document.getElementById("annoted_spo");
    annoted_spo_obj.innerHTML="已标注："+count_spo_lists+" 对三元组";
    var annoted_ent_obj=document.getElementById("annoted_entity");
    annoted_ent_obj.innerHTML="已标注："+count_new_entity+" 个新实体";
    var annoted_rel_obj=document.getElementById("annoted_relation");
    annoted_rel_obj.innerHTML="已标注："+count_new_relation+" 个新关系";
    var annoted_cap_obj=document.getElementById("cancle_point");
    annoted_cap_obj.innerHTML="已取消："+count_cancled_point+" 个标注点";
    cursor();
    // console.log(spo_global);//debug
    for (var i = 0; i<spo_global.length; i++) {
      if(spo_global[i][0]=='关')continue;//跳过隐含关系
      if(page_index[0]==current_sample_index)
         render_rectangle(start_end_index(page_index[1],labels_current[current_sample_index]),i);
    }
}

function add_entity(){
    if(state!="modify_able")return;
    clearTimeout(tappedTimeout);//防止变为单击，选中
    if(txtselected=="") txtselected=window.getSelection().toString();//得到选中的文字


    if(txtselected==""){//当前未选中文字
      start_end=start_end_index(current_char_index,labels_current[current_sample_index]);
      if(start_end[1]==-1&&(start_end[0]+1)<all_samples_loaded[current_sample_index].length)
        txtselected=all_samples_loaded[current_sample_index][start_end[0]]+all_samples_loaded[current_sample_index][start_end[0]+1];
      else if(start_end[1]==-1&&(start_end[0]+1)>=all_samples_loaded[current_sample_index].length) return; 
      for(var i=start_end[0];i<=start_end[1];i++)txtselected+=all_samples_loaded[current_sample_index][i];
      // ####else for(var i=start_end[0];i<=start_end[1];i++)txtselected+=all_samples_loaded[current_sample_index][i];
    }
    selected_flag=false;

    txtselected=txtselected.replace(/&nbsp;/g," ");
    to_server(true,true,txtselected,-1);
}
function add_relation(){
    if(state!="modify_able")return;
    indicator('off');
    clearTimeout(tappedTimeout);//防止变为单击，选中
    if(txtselected=="") txtselected=window.getSelection().toString();
    if(txtselected==""){
      start_end=start_end_index(current_char_index,labels_current[current_sample_index]);
      if(start_end[1]==-1&&(start_end[0]+1)<all_samples_loaded[current_sample_index].length)txtselected=all_samples_loaded[current_sample_index][start_end[0]]+all_samples_loaded[current_sample_index][start_end[0]+1];
      else return;
      for(var i=start_end[0];i<=start_end[1];i++)txtselected+=all_samples_loaded[current_sample_index][i];
    }

    selected_flag=false;
    txtselected=txtselected.replace(/&nbsp;/g," ");
    to_server(true,false,txtselected,-1);
}
function cancle(){
    if(state=='choosing'){
      number_record('10');
      return;
    }
    if(state!="modify_able")return;
    selected_flag=false;
    if(txtselected=="") txtselected=window.getSelection().toString();
    var start_end_tmp=start_end_index(current_char_index,labels_current[current_sample_index]);
    if(txtselected!=""){
        labels_current[current_sample_index][current_char_index]='O';
        for (var j = current_char_index+1; j<labels_current[current_sample_index].length; j++) {
            if(labels_current[current_sample_index][j][0]!="I"&&j>=(end_char_index)) break;//一直改变标签直到末尾
            labels_current[current_sample_index][j]='O';
        }
        var cancle_poin_obj=document.getElementById("cancle_point");
        cancle_poin_obj.style.innerHTML="gray";
        count_cancled_point+=1;
    }else if(start_end_tmp[0]!=-1){//选中后取消
            if(start_end_tmp[1]==-1){
                labels_current[current_sample_index][start_end_tmp[0]]='O';
                for (var j = start_end_tmp[0]+1; j<labels_current[current_sample_index].length; j++) {
                    if(labels_current[current_sample_index][j][0]!='I')break;
                    labels_current[current_sample_index][j]='O';
                }
            }else{
                for (var j = start_end_tmp[0]; j<=start_end_tmp[1]; j++) {
                    labels_current[current_sample_index][j]='O';
                }

            }
        var cancle_poin_obj=document.getElementById("cancle_point");
        cancle_poin_obj.style.innerHTML="gray";
        count_cancled_point+=1;
    }
    txtselected="";
    spo_global=[];
    indicator('off');
    refresh();
}
function queery_2dlist(list2d,list1d){
  for(var i in list2d){
    var flag=true;
    for(var j in list2d[i]){
      if(list2d[i][j]!=list1d[j]){
        flag=false;
        break;
      }
    }
    if(flag) return i;
  }
  return -1;

}
function spo_record(start_end_tmp){
  if(spo_global.indexOf(total_char_index)!=-1||labels_current[current_sample_index][start_end_tmp[0]][0]!="B")return;

        spo_global.push(total_char_index);
        // console.log(spo_global);//dev
        if(spo_global.length==3){
          save_spo();

        }else if(spo_global.length==2&&labels_current[total_char_index_2_relative_index(parseInt(spo_global[1]))[0]][total_char_index_2_relative_index(parseInt(spo_global[1]))[1]][2]=='实'&&labels_current[total_char_index_2_relative_index(parseInt(spo_global[0]))[0]][total_char_index_2_relative_index(parseInt(spo_global[0]))[1]][2]=='实'){
            implicit_relation_flag=true;
            type_choose(false,{"预测值":"服务器不可用","可信度":"0"});//直接选择两个实体之间的关系
        }else indicator('on');


}
document.documentElement.addEventListener('mousedown', function (event) {
    if(!imported_flag||state!='modify_able')return;
    obj_mousedown = event.target.tagName=="SPAN"?event.target:obj_mousedown;
})
document.documentElement.addEventListener('mouseup', function (event) {
  if(!imported_flag||state!='modify_able')return;
    obj_mouseup = event.target.tagName=="SPAN"?event.target:obj_mouseup;
    start_end=[lists.indexOf(obj_mousedown),lists.indexOf(obj_mouseup)];//鼠标选中文本释放后，立即更新start_end全局变量
    change_cursor_index(start_end[0]);
})
document.documentElement.addEventListener('click', function (event) {
  var item = event.target;
  if(imported_flag==0||state!='modify_able')return;


  if(item.tagName=="SPAN"){
    var tappedNow = item;
        current_char_index=lists.indexOf(item);

        if(current_char_index==-1){//点击的地方无效或者
            return;
        }
        change_cursor_index(current_char_index);//移动光标，快速响应
        cursor();
      if (tappedTimeout && tappedBefore) {
        clearTimeout(tappedTimeout);
      }

      if(tappedBefore == tappedNow) {
        tappedBefore = null;
        click_handle(current_char_index,true);
      } else {
        tappedTimeout = setTimeout(function(){
            tappedBefore = null;
            click_handle(current_char_index,false);
        }, 195);
        tappedBefore = tappedNow;

      }

  }else if(window.getSelection().toString()!="" && $(item).attr("id")=="CurrentContent"){////处理双击文字选中的情况
    var txt=window.getSelection().toString();
        current_char_index=Math.min(lists.indexOf(obj_mousedown),lists.indexOf(obj_mouseup));
        end_char_index= Math.max(lists.indexOf(obj_mousedown),lists.indexOf(obj_mouseup));
        if(current_char_index==-1){
            window.getSelection().removeAllRanges();
            return;
        }
        cursor_index=current_char_index;
        cursor_obj=lists[cursor_index];
        cursor_obj.style.color='#4a4948';
        var selected_obj=document.getElementById("selected");
        selected_obj.innerHTML=txt+" : "+total_char_index;
  }else if(item.tagName=="BUTTON"){
        return;
    }
    else{
        lock_flag=false;
        spo_global=[];//点击空白处，清除已有的spo，清楚选中的方框
        sp_lock=[];
        indicator('off');
        clean_rectangle();
    }
})
function click_handle(current_char_index,lock){
    //处理鼠标单击的情况
        if(lock)lock_flag=lock;
        start_end=start_end_index(current_char_index,labels_current[current_sample_index]);

        if(start_end[0]==-1||start_end[1]==-1)return;
        total_char_index=total_char_index_cal(start_end[0]);
    //单击未锁定且重复点击
    if(!lock&&(spo_global.indexOf(total_char_index)!=-1||labels_current[current_sample_index][start_end[0]][0]!="B"||(labels_current[current_sample_index][start_end[0]][2]!="实")&&(spo_global.length==0))){//重复点击、所选头字符标签不是B、第一个元素点击关系的情况
        clean_rectangle();

        //恢复已锁定的三元组病可视化
        if(sp_lock.length!=0){
              spo_global=[];
              indicator('on');
            for(var i in sp_lock){
              var se_tmp=start_end_index(total_char_index_2_relative_index(parseInt(sp_lock[i]))[1],labels_current[current_sample_index]);
              if(i==1&&labels_current[current_sample_index][se_tmp[0]][2]=='实')break;//两个实体被锁定，只取第一个锁定的实体
              render_rectangle(se_tmp,i);
              spo_global.push(sp_lock[i]);
            }


            }
            else{//没有锁定的三元组，清空相关变量
              spo_global=[];
              indicator('off');
            }
            return;
    }
    change_cursor_index(start_end[0]);
    if(lock&&labels_current[current_sample_index][start_end[0]][0]=="B"&&sp_lock.indexOf(total_char_index)==-1&&sp_lock.length<2){//双击锁定新元素
          window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
          sp_lock.push(total_char_index+'');
          for(var i in sp_lock)  render_rectangle(start_end_index(total_char_index_2_relative_index(parseInt(sp_lock[i]))[1],labels_current[current_sample_index]),i);
    }else{//只是选中元素
      render_rectangle(start_end);
    }

    //记录三元组，进行处理
    spo_record(start_end);
}
function total_char_index_2_relative_index(total_char_index_tmp){
  for(var i=0;i<all_spos_loaded.length;i++){
    if(total_char_index_tmp<all_spos_loaded[i][0][0])break //和每个页面起始索引值进行对比 <= not correcte
  }
  var page_tmp=(i-1)==all_spos_loaded.length?-1:(i-1);
  var relative_index_tmp=total_char_index_tmp-all_spos_loaded[page_tmp][0][0];
  relative_index_tmp=relative_index_tmp>=all_samples_loaded[page_tmp].length? all_samples_loaded[page_tmp].length-1:relative_index_tmp;
  return [page_tmp,relative_index_tmp]//返回页码数和本页的相对索引值
}
function total_char_index_cal(current_index){
    return current_index+parseInt(all_spos_loaded[current_sample_index][0][0]);
}
function clean_rectangle(){
    for(var i in lists)lists[i].style.border="None";
}
function columnlize(contents){
    var contents_columnlized=[];
    var cut_flag=false;
    var cut_starti=-1;
    contents=contents.replace(/\t/g,'  ');//缩进符用双空格代替
    for(var i in contents) {
      if(contents[i]=='\n'&&i<contents.length-1&&contents[parseInt(i)+1]=='\n'){
        cut_flag=true;
        cut_starti=i;
        contents_columnlized.push("_切分符_");
        continue;
      }
      if(cut_flag){
        if(parseInt(i)==(parseInt(cut_starti)+1)) cut_flag=false;
        else continue;
      }
      contents_columnlized.push(contents[i]=="\n"? "_换行符_":contents[i]);
      
    }
    return contents_columnlized.join("\n");
}
$("#fileImport").click(function () {
            $("#files").click();
        })
        function fileImport() {
            document.activeElement.blur();
            //获取读取我文件的File对象
            var selectedFile = document.getElementById('files').files[0];
            imported_flag=0;
            if(selectedFile==undefined)return;
            var name = selectedFile.name;//读取选中文件的文件名
            var size = selectedFile.size;//读取选中文件的大小
            document.getElementById('filename').innerHTML=name;
            filename=name[name.length-1]=="t"? name:name.slice(0,name.length-5);
            var reader = new FileReader();//这是核心,读取操作就是由它完成.
            reader.readAsText(selectedFile);//读取文件的内容,也可以读取文件的URL
            reader.onload = function () {
                //当读取完成后回调这个函数,然后此时文件的内容存储到了result中,直接操作即可
                txts=this.result;
                var samples=[];
                var labels=[];
                var tmp="";
                var label_tmp=[];
                var spo_tmp=[];
                var spo_dic_tmp=[];
                var spo_lists_per_page=[['0','0','0']];
                var mode=-1;
                cursor_index=0;
                count_spo_lists=0;
                imported_flag=1;
                all_spos_loaded=[];
                contents=txts.split("\n");
                if(contents[0].indexOf("\t")==-1)contents=columnlize(txts).split("\n");

                mode=contents[0].split("\t").length;
                var cut_manualy_flag=false;//手动切分或者自动切分
                for(i in contents){
                    if(contents[i].length==0)continue;//空行
                    c_l=contents[i].split("\t");
                      // if(c_l.length!=mode){//标注完整性检查
                      //     alert(i+'处标注存在问题！\n'+c_l.length+'!='+mode);
                      //
                      //     return;
                      // }
                      if(c_l.length>=3){//包含三元组空间，读取进来
                          spo_read=c_l[2];
                          if(spo_read[0]!="X"){//存在三元组标记
                              var spos=spo_read.split(";");//尝试切分多个三元组
                              for(var k in spos){
                                  var spos_char=[];
                                  var spo_tmp_char=spos[k].split(">");//切分单个三元组
                                  // for(var j in spo_tmp_number)spos_number.push(parseInt(spo_tmp_number[j]));
                                  for(var j in spo_tmp_char)spos_char.push(spo_tmp_char[j]);
                                  if(queery_2dlist(spo_lists_per_page,spos_char)==-1){
                                        spo_lists_per_page.push(spos_char);
                                        count_spo_lists+=1;
                                  } 
                                  else console.log('发现重复三元组：'+spos_char);//output
                                  
                                  }
                              }
                          }

                      c=c_l[0];
                      if(c_l.length==1)l="O";//原始文本，无标注
                      else l=c_l[1];


                    // if((c=="。" ||c=='_换行符_')&&(tmp.length>400)){
                      if(c=='_切分符_'){
                          cut_manualy_flag=true;
                          c= c=='_切分符_' ? "\n" : c;
                          tmp+=c;
                          label_tmp.push(l);
                          samples.push(tmp);
                          all_spos_loaded.push(spo_lists_per_page);
                          var page_index=parseInt(i)+1;
                          spo_lists_per_page=[[page_index+'',page_index+'',page_index+'']];
                          labels.push(label_tmp);
                          if(tmp.length!=label_tmp.length){
                              console.log(tmp.length);
                              console.log(label_tmp.length);
                              alert('分割时，tmp 和 label_tmp长度不同！');
                              return;
                          }
                          label_tmp=[];
                          tmp="";
                      }else  if((!cut_manualy_flag)&&(c=='_换行符_')&&(tmp.length>400)){
                          c= c=='_换行符_' ? "\n" : c;
                          tmp+=c;
                          label_tmp.push(l);
                          samples.push(tmp);
                          all_spos_loaded.push(spo_lists_per_page);
                          var page_index=parseInt(i)+1;
                          spo_lists_per_page=[[page_index+'',page_index+'',page_index+'']];
                          labels.push(label_tmp);
                          if(tmp.length!=label_tmp.length){
                              console.log(tmp.length);
                              console.log(label_tmp.length);
                              alert('分割时，tmp 和 label_tmp长度不同！');
                              return;
                          }
                          label_tmp=[];
                          tmp="";
                    }else{
                          c= c=='_换行符_' ? "\n" : c;

                      tmp+=c;
                          label_tmp.push(l);
                          if(tmp.length!=label_tmp.length){
                              console.log(tmp.length);
                              console.log(label_tmp.length);
                              alert('字符和标签长度不对应，检查数据！');
                              return;
                          }
                    }
                  }

                  if(samples.indexOf(tmp)==-1&&tmp!=""&&tmp!="\n"){//追加剩下的，同时排除空和只有一个换行符的情况。
                      samples.push(tmp);
                      labels.push(label_tmp);
                      all_spos_loaded.push(spo_lists_per_page);
                  }

                  current_sample_index=-1;
                  if(filename.indexOf("#")!=-1){//尝试从文件名中读取上次标注页码
                      page_saved=filename.split("#");
                      if(page_saved.length==3){
                          current_sample_index=parseInt(page_saved[1]);
                          // for(var i=0;i<=current_sample_index;i++)page_predicted.push(i);//标注过的页面不再进行预测
                          filename=page_saved[0];
                          }
                      }else  page_predicted=[];
                  if(current_sample_index==-1||current_sample_index>=all_spos_loaded.length){
                      current_sample_index=0;//初始页码
                      filename+=".";
                  }
                  // current_sample_index=0;//for debug
                  cursor_index=0;
                  total=samples.length-1;
                  count_new_entity=0;
                  count_new_relation=0;
                  count_cancled_point=0;
                  var jump_option_object=document.getElementById("jump");
                  jump_option_object.options.length=0;
                  for(var i=0;i<samples.length;i++){
                      var option_obj=document.createElement("option");
                      option_obj.value=i;
                      option_obj.innerHTML=i;
                      jump_option_object.appendChild(option_obj);
                  }
                  all_samples_loaded=samples;
                  labels_current=labels;
                  spo_global=[];
                  sp_lock=[];

                  if(seqlab_flag&&page_predicted.indexOf(current_sample_index)==-1){
                    page_predicted.push(current_sample_index);
                    seq_labing_to_server(seqlab_flag,all_samples_loaded[current_sample_index]);
                  }
                  refresh();
                  indicator('off');
                    document.activeElement.blur();
                  //初始化视野
                  var position=cursor_obj.getBoundingClientRect();
                  view_adjust(position);
                  state="modify_able";
              }

        }
</script>
</body>
